package org.jeecg.modules.zixishi.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jeecg.common.api.dto.message.BusTemplateMessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.CommonSendStatus;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SysAnnmentTypeEnum;
import org.jeecg.modules.coupon.entity.Coupon;
import org.jeecg.modules.coupon.entity.MyCoupon;
import org.jeecg.modules.coupon.service.ICouponService;
import org.jeecg.modules.coupon.service.IMyCouponService;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.order.entity.Order;
import org.jeecg.modules.order.service.IOrderService;
import org.jeecg.modules.recharge.entity.Balance;
import org.jeecg.modules.recharge.entity.OrderRecharge;
import org.jeecg.modules.recharge.service.IBalanceService;
import org.jeecg.modules.recharge.service.IOrderRechargeService;
import org.jeecg.modules.zixishi.entity.Quyu;
import org.jeecg.modules.zixishi.entity.Seat;
import org.jeecg.modules.zixishi.entity.Zixishi;
import org.jeecg.modules.zixishi.service.*;
import org.jeecg.modules.zixishi.vo.ZixishiPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @Author: jeecg-boot
* @Date:   2024-05-19
* @Version: V1.0
*/
@Api(tags="首页API")
@RestController
@RequestMapping("/index")
@Slf4j
public class IndexController {
    @Autowired
    private IOrderRechargeService rechargeService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IMyCouponService myCouponService;

    @Autowired
    private IAnalysisService analysisService;

    @Autowired
    RedisUtil redisUtil;

    @GetMapping(value = "/chartCard")
    public Result<Map> chartCardData(HttpServletResponse resp) {
        Map retMap = new HashMap();

        Map rechargeMap = new HashMap();
        retMap.put("rechargeMap", rechargeMap);
        QueryWrapper<OrderRecharge> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("IFNULL(sum(recharge_total),0) as rechargeTotal")
                .eq("pay_status", "1");
        Map<String, Object> rechargeTotal = rechargeService.getMap(queryWrapper);
        Double totalMoney = (Double) rechargeTotal.get("rechargeTotal");
        rechargeMap.put("totalMoney",totalMoney.floatValue());

        List<OrderRecharge> rechargeList = rechargeService.list(new LambdaQueryWrapper<OrderRecharge>()
                .eq(OrderRecharge::getPayStatus,"1").gt(OrderRecharge::getCreateTime,DateUtils.addWeeks(new Date(),-14)));

        if(CollectionUtil.isNotEmpty(rechargeList)){
            BigDecimal todayMoney = new BigDecimal(0);
            BigDecimal yesterdayMoney = new BigDecimal(0);
            BigDecimal weekMoney = new BigDecimal(0);
            BigDecimal lastweekMoney = new BigDecimal(0);
            for(OrderRecharge recharge:rechargeList){
                BigDecimal amt = new BigDecimal(recharge.getRechargeTotal());
                if(DateUtils.isSameDay(new Date(),recharge.getCreateTime())){
                    todayMoney = todayMoney.add(amt);
                }else if(DateUtils.isSameDay(DateUtils.addDays(new Date(),-1),recharge.getCreateTime())){
                    yesterdayMoney = yesterdayMoney.add(amt);
                }else if(DateUtil.isSameWeek(new Date(),recharge.getCreateTime(),true)){
                    weekMoney = weekMoney.add(amt);
                }else if(DateUtil.isSameWeek(DateUtils.addWeeks(new Date(),-1),recharge.getCreateTime(),true)){
                    lastweekMoney = lastweekMoney.add(amt);
                }
            }

            float weekPercent = lastweekMoney.intValue() == 0? 100: NumberUtil.div(weekMoney.subtract(lastweekMoney), lastweekMoney,2).multiply(BigDecimal.valueOf(100)).floatValue();
            float dayPercent = yesterdayMoney.intValue() == 0? 100: NumberUtil.div(todayMoney.subtract(yesterdayMoney), yesterdayMoney,2).multiply(BigDecimal.valueOf(100)).floatValue();

            rechargeMap.put("todayMoney",todayMoney);
            rechargeMap.put("weekPercent",weekPercent + "%");
            rechargeMap.put("dayPercent",dayPercent + "%");

            Map rechargeOrderMap = new HashMap();
            retMap.put("rechargeOrderMap", rechargeOrderMap);

            List<Map> rechargeOrderData = new ArrayList<>();
            Map<String,Integer> map = new HashMap<>();
            for(OrderRecharge recharge:rechargeList){
                String date = DateUtil.formatDate(recharge.getCreateTime());
                Integer cnt = map.get(date);
                cnt = cnt == null ? 1 : cnt + 1;
                map.put(date,cnt);
            }
            Iterator<String> iter = map.keySet().iterator();
            while(iter.hasNext()){
                String date = iter.next();
                Integer cnt = map.get(date);
                Map<String,Object> map1 = new HashMap<String,Object>(){{
                    put("x",date);
                    put("y",cnt);
                }};
                rechargeOrderData.add(map1);
            }
            rechargeOrderMap.put("rechargeOrderData",rechargeOrderData);
            long rechargeTotalCnt = rechargeService.count(new LambdaQueryWrapper<OrderRecharge>()
                    .eq(OrderRecharge::getPayStatus,"1"));
            long rechargeDayCnt = rechargeService.count(new LambdaQueryWrapper<OrderRecharge>()
                    .eq(OrderRecharge::getPayStatus,"1")
                    .apply(true, "TO_DAYS(NOW())-TO_DAYS(create_time) = 0"));
            rechargeOrderMap.put("rechargeTotalCnt",rechargeTotalCnt);
            rechargeOrderMap.put("rechargeDayCnt",rechargeDayCnt);
        }
        Map orderMap = new HashMap();
        retMap.put("orderMap", orderMap);
        List<Order> orderList = orderService.list(new LambdaQueryWrapper<Order>()
                .in(Order::getOrderStatus,Arrays.asList("1", "2", "3"))
                .ge(Order::getCreateTime,DateUtils.addDays(new Date(),-7)));
        long orderTotalCnt = orderService.count(new LambdaQueryWrapper<Order>()
                .in(Order::getOrderStatus,Arrays.asList("1", "2", "3")));
        long orderDayCnt = orderService.count(new LambdaQueryWrapper<Order>()
                .in(Order::getOrderStatus,Arrays.asList("1", "2", "3"))
                .apply(true, "TO_DAYS(NOW())-TO_DAYS(create_time) = 0"));
        orderMap.put("orderTotalCnt",orderTotalCnt);
        orderMap.put("orderDayCnt",orderDayCnt);
        List<Map> orderData = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(orderList)){
            Map<String,Integer> map = new HashMap<>();
            for(Order order:orderList){
                String date = DateUtil.formatDate(order.getCreateTime());
                Integer cnt = map.get(date);
                cnt = cnt == null ? 1 : cnt + 1;
                map.put(date,cnt);
            }
            Iterator<String> iter = map.keySet().iterator();
            while(iter.hasNext()){
                String date = iter.next();
                Integer cnt = map.get(date);
                Map<String,Object> map1 = new HashMap<String,Object>(){{
                    put("x",date);
                    put("y",cnt);
                }};
                orderData.add(map1);
            }
            orderMap.put("orderData",orderData);
        }

        Map couponMap = new HashMap();
        retMap.put("couponMap", couponMap);
        long totalCoupon = myCouponService.count();
        couponMap.put("totalCoupon",totalCoupon);
        long usedCoupon = myCouponService.count(new LambdaQueryWrapper<MyCoupon>().eq(MyCoupon::getUseStatus,1));
        couponMap.put("usedPercent",String.format("%.2f",NumberUtil.div(usedCoupon,totalCoupon,2)*100));
        List<MyCoupon> couponList = myCouponService.list(new LambdaQueryWrapper<MyCoupon>()
                .ge(MyCoupon::getCreateTime,DateUtils.addDays(new Date(),-7)));

        List<Map> couponData = new ArrayList<>();
        couponMap.put("couponData",couponData);
        if(CollectionUtil.isNotEmpty(couponList)){
            Map<String,Integer> map = new HashMap<>();
            for(MyCoupon myCoupon:couponList){
                String date = DateUtil.formatDate(myCoupon.getCreateTime());
                Integer cnt = map.get(date);
                cnt = cnt == null ? 1 : cnt + 1;
                map.put(date,cnt);
            }
            Iterator<String> iter = map.keySet().iterator();
            while(iter.hasNext()){
                String date = iter.next();
                Integer cnt = map.get(date);
                Map<String,Object> map1 = new HashMap<String,Object>(){{
                    put("x",date);
                    put("y",cnt);
                }};
                couponData.add(map1);
            }
        }
        return Result.ok(retMap);
    }

    @GetMapping(value = "/topn")
    public Result<Map> topn(HttpServletRequest request) {
        List<Map> userList = orderService.topnUser();
        List<Map> seatList = orderService.topnSeat();
        Map map = new HashMap();
        map.put("userList",userList);
        map.put("seatList",seatList);
        return Result.ok(map);
    }

    @GetMapping("/orderAnalysis")
    public Result<Map> orderAnalysis(@DateTimeFormat(pattern="yyyy-MM-dd") Date startDay,@DateTimeFormat(pattern="yyyy-MM-dd") Date endDay) {
        Map orderMap = analysisService.orderAnalysis(startDay,endDay);
        return Result.ok(orderMap);
    }

    @GetMapping("/orderCharts")
    public Result<List> orderCharts(@DateTimeFormat(pattern="yyyy-MM-dd") Date startDay,@DateTimeFormat(pattern="yyyy-MM-dd") Date endDay) {
        List<Map> chartList = analysisService.orderCharts(startDay,endDay);
        return Result.ok(chartList);
    }

    @GetMapping("/userAnalysis")
    public Result<Map> userAnalysis(@DateTimeFormat(pattern="yyyy-MM-dd") Date startDay,@DateTimeFormat(pattern="yyyy-MM-dd") Date endDay) {
        Map userMap = analysisService.userAnalysis(startDay,endDay);
        return Result.ok(userMap);
    }

    @GetMapping("/userCharts")
    public Result<List> userCharts(@DateTimeFormat(pattern="yyyy-MM-dd") Date startDay,@DateTimeFormat(pattern="yyyy-MM-dd") Date endDay) {
        List<Map> chartList = analysisService.userCharts(startDay,endDay);
        return Result.ok(chartList);
    }
}
